package com.atguigu.gmall.service.TreadPool;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程池自动配置类
 */
@EnableConfigurationProperties(AppTreadPoolProperties.class)
@Configuration
public class AppTreadPoolAutoConfiguration {

//
//    @Autowired
//    ThreadPoolExecutor corePool;
    //ThreadPoolExecutor
    //@Bean参数位置属性自动从容器中要
    @Primary
    @Bean
    public ThreadPoolExecutor corePool(AppTreadPoolProperties appTreadPoolProperties,
                                       @Value("${spring.application.name:default}") String appName){
        /**
         * int corePoolSize,
         * int maximumPoolSize,
         * long keepAliveTime,
         * TimeUnit unit,
         * BlockingQueue<Runnable> workQueue,
         * ThreadFactory threadFactory,
         * RejectedExecutionHandler handler
         */

      return   new ThreadPoolExecutor(
              appTreadPoolProperties.getCorePoolSize(),
              appTreadPoolProperties.getMaximumPoolSize(),
              appTreadPoolProperties.getKeepAliveTime(),
              appTreadPoolProperties.getUnit(),
              new LinkedBlockingQueue<>(appTreadPoolProperties.getQueueSize()),
              new AppThreadFactory("["+appName+"]"+"-core"),
              appTreadPoolProperties.getRejectedHandler()
      );
    }

    @Bean
    public ThreadPoolExecutor otherPool(AppTreadPoolProperties appTreadPoolProperties,
                                       @Value("${spring.application.name:default}") String appName){
        /**
         * int corePoolSize,
         * int maximumPoolSize,
         * long keepAliveTime,
         * TimeUnit unit,
         * BlockingQueue<Runnable> workQueue,
         * ThreadFactory threadFactory,
         * RejectedExecutionHandler handler
         */

        return   new ThreadPoolExecutor(
                appTreadPoolProperties.getCorePoolSize()/2,
                appTreadPoolProperties.getMaximumPoolSize()/2,
                appTreadPoolProperties.getKeepAliveTime(),
                appTreadPoolProperties.getUnit(),
                new LinkedBlockingQueue<>(appTreadPoolProperties.getQueueSize()/2),
                new AppThreadFactory("["+appName+"]"+"-other"),
                appTreadPoolProperties.getRejectedHandler()
        );
    }



      class AppThreadFactory implements ThreadFactory{
        private String appName;
        private AtomicInteger count = new AtomicInteger(1);
        public AppThreadFactory(String appName){
            this.appName = appName;
        }
          @Override
          public Thread newThread(Runnable r) {
              Thread thread = new Thread(r);

                thread.setName(appName+count.getAndIncrement());
              return thread;
          }
      }


}
